Spring解决方案:
- 添加注解@CrossOrigin ,该注解可以添加到方法上也可以加到Controller上。
- 自定义配置WebMvcConfig, 重写addCorsMapping方法。
- 通过过滤器CorsFilter, 在WebMvcConfig中配置Filter
细节后续
Spring解决方案:
细节后续
HTML(超文本标记语言—HyperText Markup Language)是构成 Web 世界的基础,是一种用来告知浏览器如何组织页面的标记语言
超文本 Hypertext,是指连接单个或者多个网站间的网页的链接。通过链接,就能访问互联网中的内容
标记 Markup ,是用来注明文本,图片等内容,以便于在浏览器中显示,例如 <head>,<body> 等
网页的构成
参考视频:https://www.bilibili.com/video/BV1Qf4y1T7Hx
HTML 页面由一系列的元素(elements) 组成,而元素是使用标签创建的
一对标签(tags)可以设置一段文字样式,添加一张图片或者添加超链接等等
在 HTML 中,<h1> 标签表示标题,我们可以使用开始标签和结束标签包围文本内容,这样其中的内容就以标题的形式显示
1 | <h1>开始学习JavaWeb</h1> |
HTML 标签可以拥有属性
'' 或者 "" 括起来。 不加引号也是可以的(不建议使用)。比如:name=’value’1 | <h1 align="center">开始学习JavaWeb</h1> |
在 HTML 标签中,align 属性表示水平对齐方式,我们可以赋值为 center 表示 居中 。

文档结构介绍:
<!DOCTYPE html>是 HTML5 的声明<meta charset="utf-8">:这个标签是页面的元数据信息,设置文档使用 utf-8 字符集编码<title>:这个标签定义文档标题,位置出现在浏览器标签。在收藏页面时,它可用来描述页面将一段 HTML 中的内容置为注释,你需要将其用特殊的记号 包括起来
1 | <p>我在注释外!</p> |
一些元素只有一个标签,叫做空元素。它是在开始标签中进行关闭的。
1 | 第一行文档<br/> |
把元素放到其它元素之中——这被称作嵌套。
1 | <h2><u>二级标题</u></h2> |
在HTML中有两种重要元素类别,块级元素和内联元素
块级元素:
独占一行。块级元素(block)在页面中以块的形式展现。相对于其前面的内容它会出现在新的一行,其后的内容也会被挤到下一行展现。比如<p> ,<hr>,<li> ,<div>等。
行内元素
行内显示。行内元素不会导致换行。通常出现在块级元素中并环绕文档内容的一小部分,而不是一整个段落或者一组内容。比如<b>,<a>,<i>,<span> 等。
注意:一个块级元素不会被嵌套进行内元素中,但可以嵌套在其它块级元素中。
常用的两个标签:(重要)
<div> 是一个通用的内容容器,并没有任何特殊语义。它可以被用来对其它元素进行分组,一般用于样式化相关的需求。它是一个块级元素。 <span> 是短语内容的通用行内容器,并没有任何特殊语义。它可以被用来编组元素以达到某种样式。它是一个行内元素标签属性,主要用于拓展标签。属性包含元素的额外信息,这些信息不会出现在实际的内容中。但是可以改变标签的一些行为或者提供数据,属性总是以name = value"的格式展现。
属性名:同一个标签中,属性名不得重复。
大小写:属性和属性值对大小写不敏感。不过W3C标准中,推荐使用小写的属性/属性值。
引号:双引号是最常用的,不过使用单引号也没有问题。
常用属性:
| 属性名 | 作用 |
|---|---|
| class | 定义元素类名,用来选择和访问特定的元素 |
| id | 定义元素唯一标识符,在整个文档中必须是唯一的 |
| name | 定义元素名称,可以用于提交服务器的表单字段 |
| value | 定义在元素内显示的默认值 |
| style | 定义CSS样式,这些样式会覆盖之前设置的样式 |
在HTML中,字符 <, >,",' 和 & 是特殊字符
| 原义字符 | 等价字符引用 |
|---|---|
| < | < |
| > | > |
| “ | " |
| ‘ | ' |
| & | & |
| 空格 | |
使用文本内容标签设置文字基本样式
| 标签名 | 作用 |
|---|---|
| p | 表示文本的一个段落 |
| h | 表示文档标题,<h1>–<h6> ,呈现了六个不同的级别的标题,<h1> 级别最高,而 <h6> 级别最低 |
| hr | 表示段落级元素之间的主题转换,一般显示为水平线 |
| li | 表示列表里的条目。(常用在ul ol 中) |
| ul | 表示一个无序列表,可含多个元素,无编号显示。 |
| ol | 表示一个有序列表,通常渲染为有带编号的列表 |
| em | 表示文本着重,一般用斜体显示 |
| strong | 表示文本重要,一般用粗体显示 |
| font | 表示字体,可以设置样式(已过时) |
| i | 表示斜体 |
| b | 表示加粗文本 |
1 |
|
效果如下:

img标签中的img其实是英文image的缩写, img标签的作用, 就是告诉浏览器我们需要显示一张图片
1 | <img src="../img/b.jpg" width="400px" height="200px" alt="" title=""/> |
| 属性名 | 作用 |
|---|---|
| src | 图片路径 |
| title | 鼠标悬停(hover)时显示文本。 |
| alt | 图片描述,图形不显示时的替换文本。 |
| height | 图像的高度。 |
| width | 图像的宽度。 |
超链接标签的作用: 就是用于控制页面与页面(服务器资源)之间跳转的
1 | <a href="指定需要跳转的目标路径" target="打开的方式">需要展现给用户的内容</a> |
1 |
|
效果图:
form 表示表单,是用来收集用户输入信息并向 Web 服务器提交的一个容器
1 | <form > |
| 属性名 | 作用 |
|---|---|
| action | 处理此表单信息的Web服务器的URL地址 |
| method | 提交此表单信息到Web服务器的方式,可能的值有get和post,默认为get |
| autocomplete | 自动补全,指示表单元素是否能够拥有一个默认值,配合input标签使用 |
get与post区别:
post:指的是 HTTP POST 方法;表单数据会包含在表单体内然后发送给服务器。
get:指的是 HTTP GET 方法;表单数据会附加在 action 属性的URI中,并以 ‘?’ 作为分隔符,然后这样得到的 URI 再发送给服务器。
| 地址栏可见 | 数据安全 | 数据大小 | |
|---|---|---|---|
| GET | 可见 | 不安全 | 有限制(取决于浏览器) |
| POST | 不可见 | 相对安全 | 无限制 |
| 标签名 | 作用 | 备注 |
|---|---|---|
| label | 表单元素的说明,配合表单元素使用 | for属性值为相关表单元素id属性值 |
| input | 表单中输入控件,多种输入类型,用于接受来自用户数据 | type属性值决定输入类型 |
| button | 页面中可点击的按钮,可以配合表单进行提交 | type属性值决定按钮类型 |
| select | 表单的控件,下拉选项菜单 | 与option配合实用 |
| optgroup | option的分组标签 | 与option配合实用 |
| option | select的子标签,表示一个选项 | |
| textarea | 表示多行纯文本编辑控件 | |
| fieldset | 用来对表单中的控制元素进行分组(也包括 label 元素) | |
| legend | 用于表示它的fieldset内容的标题。 | fieldset 的子元素 |
button标签:表示按钮
| 属性值 | 作用 | 备注 |
|---|---|---|
| button | 无行为按钮,用于结合JavaScript实现自定义动态效果 | 同 <input type="submit"/> |
| submit | 提交按钮,用于提交表单数据到服务器。 | 同 <input type="submit"/> |
| reset | 重置按钮,用于将表单中内容恢复为默认值。 | 同<input type="reset"/> |
label标签:表单的说明。
input标签:输入控件。
属性:
1 | <body> |
效果图:
| 属性名 | 作用 |
|---|---|
| name | <input>的名字,在提交整个表单数据时,可以用于区分属于不同<input>的值 |
| value | 这个<input>元素当前的值,允许用户通过页面输入 |
使用方式:以name属性值作为键,value属性值作为值,构成键值对提交到服务器,多个键值对浏览器使用&进行分隔。

| 属性值 | 作用 | 备注 |
|---|---|---|
| text | 单行文本字段 | |
| password | 单行文本字段,值被遮盖 | |
| 用于编辑 e-mail 的字段,可以对e-mail地址进行简单校验 | ||
| radio | 单选按钮。 1. 在同一个”单选按钮组“中,所有单选按钮的 name 属性使用同一个值;一个单选按钮组中是,同一时间只有一个单选按钮可以被选择。 2. 必须使用 value 属性定义此控件被提交时的值。 3. 使用checked 必须指示控件是否缺省被选择。 | |
| checkbox | 复选框。 1. 必须使用 value 属性定义此控件被提交时的值。 2. 使用 checked 属性指示控件是否被选择。 3. 选中多个值时,所有的值会构成一个数组而提交到Web服务器 | |
| date | HTML5 用于输入日期的控件 | 年,月,日,不包括时间 |
| time | HTML5 用于输入时间的控件 | 不含时区 |
| datetime-local | HTML5 用于输入日期时间的控件 | 不包含时区 |
| number | HTML5 用于输入浮点数的控件 | |
| range | HTML5 用于输入不精确值控件 | max-规定最大值min-规定最小值 step-规定步进值 value-规定默认值 |
| search | HTML5 用于输入搜索字符串的单行文本字段 | 可以点击x清除内容 |
| tel | HTML5 用于输入电话号码的控件 | |
| url | HTML5 用于编辑URL的字段 | 可以校验URL地址格式 |
| file | 此控件可以让用户选择文件,用于文件上传。 | 使用 accept 属性可以定义控件可以选择的文件类型。 |
| hidden | 此控件用户在页面上不可见,但它的值会被提交到服务器,用于传递隐藏值 |
1 |
|

下拉列表标签
1 | <select name=""> |
option:选择菜单的选项
optgroup:列表项分组标签
属性:label设置分组名称
1 | <textarea name="textarea" rows="10" cols="50">Write something here</textarea> |
属性:
name-标签名称
rows-行数
cols-列数
1 | <body> |

1 | <form action="#" method="post"> |
<table> , 表示表格标签,表格是数据单元的行和列的两维表

代码展示:
1 | <table> |
效果图:
| First name | Last name |
|---|---|
| John | Doe |
| Jane | Doe |
1 | <table width="400px" border="1px" align="center"> |
效果图:

| 标签名 | 作用 | 备注 |
|---|---|---|
| thead | 定义表格的列头的行 | 一个表格中仅有一个 |
| tbody | 定义表格的主体 | 用来封装一组表行(tr元素) |
| tfoot | 定义表格的各列汇总行 | 一个表格中仅有一个 |
在head标签中,通过style标签加入样式。
基本格式:可以含有多个属性,一个属性名也可以含有多个值,同时设置多样式。
1 | <style> |
background属性用来设置背景相关的样式。
背景色
[background-color]属性定义任何元素的背景色
1 | body { |
背景图
该[background-image]属性允许在元素的背景中显示图像。使用url函数指定图片路径
1 |
|

背景重复
[background-repeat]属性用于控制图像的平铺行为。可用值:
no-repeat -停止完全重复背景repeat-x —水平重复repeat-y —竖直重复repeat—默认值;双向重复1 | body { |

div简单布局:
1 | <style> |

class值
可以设置宽度,浮动,背景
1 | .class值{ |
属性
background:背景颜色
width:宽度 (npx 或者 n%)
height:长度
text-align:文本对齐方式
background-image: url(“../img/bg.png”):背景图
float:浮动
指定一个元素应沿其容器的左侧或右侧放置,允许文本或者内联元素环绕它,该元素从网页的正常流动中移除,其他部分保持正常文档流顺序。
1 | <!-- 加入浮动 --> |
div基本布局
1 |
|

为了更好的组织文档,HTML5规范中设计了几个语义元素,可以将特殊含义传达给浏览器。
| 标签 | 名称 | 作用 | 备注 |
|---|---|---|---|
| header | 标头元素 | 表示内容的介绍 | 块元素,文档中可以定义多个 |
| nav | 导航元素 | 表示导航链接 | 常见于网站的菜单,目录和索引等,可以嵌套在header中 |
| article | 文章元素 | 表示独立内容区域 | 标签定义的内容本身必须是有意义且必须独立于文档的其他部分 |
| footer | 页脚元素 | 表示页面的底部 | 块元素,文档中可以定义多个 |

<audio>:用于播放声音,比如音乐或其他音频流,是 HTML 5 的新标签。
常用属性:
| 属性名 | 取值 | 描述 |
|---|---|---|
| src | URL | 音频资源的路径 |
| autoplay | autoplay | 音频准备就绪后自动播放 |
| controls | controls | 显示控件,比如播放按钮。 |
| loop | loop | 表示循环播放 |
| preload | preload | 音频在页面加载时进行预加载。 如果使用 “autoplay”,则忽略该属性。 |
<video> 标签用于播放视频,比如电影片段或其他视频流,是 HTML 5 的新标签。
常用属性:
| 属性名 | 取值 | 描述 |
|---|---|---|
| src | URL | 要播放的视频的 URL。 |
| width | 设置视频播放器的宽度。 | |
| height | 设置视频播放器的高度。 | |
| autoplay | autoplay | 视频在就绪后自动播放。 |
| control | controls | 显示控件,比如播放按钮。 |
| loop | loop | 如果出现该属性,则当媒介文件完成播放后再次开始播放。 |
| preload | preload | 视频在页面加载时进行加载。 如果使用 “autoplay”,则忽略该属性。 |
| mute | muted | 规定视频的音频输出应该被静音。 |
| poste | URL | 视频下载时显示的图像,或者视频播放前显示的图像。 |
1 |
|

在html里面锚点的作用: 通过a标签跳转到指定的位置.
1 | <a href="#aId">回到顶部</a> |
summary标签来描述概要信息, 利用details标签来描述详情信息. 默认情况下是折叠展示, 想看见详情必须点击
1 | <details> |
CSS (层叠样式表——Cascading Style Sheets,缩写为 CSS),简单的说,它是用于设置和布局网页的计算机语言。会告知浏览器如何渲染页面元素。例如,调整内容的字体,颜色,大小等样式,设置边框的样式,调整模块的间距等。
层叠:是指样式表允许以多种方式规定样式信息。可以规定在单个元素中,可以在页面头元素中,也可以在另一个CSS文件中,规定的方式会有次序的差别。
样式:是指丰富的样式外观。拿边框距离来说,允许任何设置边框,允许设置边框与框内元素的距离,允许设置边框与边框的距离等等。
CSS是一门基于规则的语言—你能定义用于你的网页中特定元素的一组样式规则。这里面提到了两个概念,一是特定元素,二是样式规则。对应CSS的语法,也就是选择器(selects)和声明(eclarations)。
font-size,width,background-color。格式:
1 | 选择器 { |

CSS中的注释以/*和开头*/。
1 | /* 设置h1的样式 */ |
内联样式是CSS声明在元素的style属性中,仅影响一个元素:
格式:
1 | <标签 style="属性名:属性值; 属性名:属性值;">内容</标签> |
例如:
1 | <h1 style="color: blue;background-color: yellow;border: 1px solid black;"> |
效果:
特点:格式简单,但是样式作用无法复用到多个元素上,不利于维护
内部样式表是将CSS样式放在style标签中,通常style标签编写在HTML 的head标签内部。
格式:
1 | <head> |
例如:
1 | <head> |
特点:内部样式只能作用在当前页面上,如果是多个页面,就无法复用了
外部样式表是CSS附加到文档中的最常见和最有用的方法,因为您可以将CSS文件链接到多个页面,从而允许您使用相同的样式表设置所有页面的样式。
外部样式表是指将CSS编写在扩展名为.css 的单独文件中,并从HTML<link> 元素引用它,通常link标签`编写在HTML 的[head]标签内部。
格式
1 | <link rel="stylesheet" href="css文件"> |
举例
创建styles.css文件
1 | h1 { |
link标签引入文件
1 |
|
效果同上
为了CSS文件的管理,在项目中创建一个css文件夹,专门保存样式文件,并调整指定的路径以匹配
1 | <link rel="stylesheet" href="../css/styles.css"> |
规则层叠于一个样式表中,其中数字 4 拥有最高的优先权:
为了样式化某些元素,我们会通过选择器来选中HTML文档中的这些元素,每个CSS规则都以一个选择器或一组选择器为开始,去告诉浏览器这些规则应该应用到哪些元素上。
选择器的分类:
| 分类 | 名称 | 符号 | 作用 | 示例 |
|---|---|---|---|---|
| 基本选择器 | 元素选择器 | 标签名 | 基于标签名匹配元素 | div{ } |
| 类选择器 | . |
基于class属性值匹配元素 | .center{ } | |
| ID选择器 | # |
基于id属性值匹配元素 | #username{ } | |
| 通用选择器 | * |
匹配文档中的所有内容 | *{ } | |
| 属性选择器 | 属性选择器 | [] |
基于某属性匹配元素 | [type]{ } |
| 伪类选择器 | 伪类选择器 | : |
用于向某些选择器添加特殊的效果 | a:hover{ } |
| 组合选择器 | 分组选择器 | , | 使用 , 号结合两个选择器,匹配两个选择器的元素 | span,p{} |
| 后代选择器 | 空格 | 使用空格符号结合两个选择器,基于 第一个选择器,匹配第二个选择器的所有后代元素 |
.top li{ } |
页面元素:
1 | <body> |
元素选择器
1 | /*选择所有div标签,字体为蓝色*/ |
类选择器
1 | /*选择class为cls的,字体为蓝色*/ |
ID选择器
1 | /*id选择器*/ |
通用选择器
1 | /*所有标签 */ |
页面:
1 | <body> |
选择器:
1 | /*输入框中输入的字符是红色*/ |
页面元素
1 | <body> |
伪类选择器
1 | /*未访问的状态*/ |
注意:伪类顺序 link ,visited,hover,active,否则有可能失效。
页面:
1 | <body> |
分组选择器
1 | /*span p两个标签下的字体为蓝色*/ |
后代选择器
1 | /*class为top下的所有li标签字体颜色为红色*/ |
选择器优先级
单个边框
border:边框
border-top: 上边框
border-left: 左边框
border-bottom: 底边框
border-right: 右边框
无边框,当border值为none时,可以让边框不显示
1 | div { |
圆角
通过使用[border-radius]属性设置盒子的圆角,虽然能分别设置四个角,但是通常我们使用一个值,来设置整体效果
1 | #d1{ |
1 | <body> |
轮廓outline:是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用
1 |
|

盒子模型是通过设置元素框与元素内容和外部元素的边距,而进行布局的方式。

内边距、边框和外边距都是可选的,默认值是零。在 CSS 中,width 和 height 指的是内容区域的宽度和高度。
外边距
单独设置边框的外边距,设置上、右、下、左方向:
1 | margin-top |
```css
margin: auto /浏览器自动计算外边距,具有居中效果。/
1 |
|
两个值
1 | margin:10px 5px;/* 上外边距和下外边距是 10px*/ |
三个值
1 | /* 上外边距是 10px,右外边距和左外边距是 5px,下外边距是 15px*/ |
四个值
1 | /*上外边距是 10px,右外边距是 5px,下外边距是 15px,左外边距是 20px*/ |
内边距
与外边距类似,单独设置边框的内边距,设置上、右、下、左方向:
1 | padding-top |
基本布局
1 | <style> |

增加内边距会增加元素框的总尺寸
1 | <style> |

| 属性名 | 作用 | 属性取值 |
|---|---|---|
| width | 宽度 | |
| height | 高度 | |
| color | 颜色 | |
| font-family | 字体样式 | 宋体、楷体 |
| font-size | 字体大小 | px : 像素,文本高度像素绝对数值。 em : 1em等于当前元素的父元素设置的字体大小,是相对数值 |
| text-decoration | 下划线 | underline : 下划线 overline : 上划线 line-through : 删除线 none : 不要线条 |
| text-align | 文本水平对齐 | lef : 左对齐文本 right : 右对齐文本 center : 使文本居中 justify : 使文本散布,改变单词间的间距,使文本所有行具有相同宽度。 |
| line-height | 行高,行间距 | |
| vertical-align | 文本垂直对齐 | top:居上 bottom:居下 middle:居中 或者百分比 |
| display | 元素如何显示 | 可以设置块级和行内元素的切换,也可以设置元素隐藏 inline:内联元素(无换行、无长宽) block:块级元素(有换行) inline-block:内联元素(有长宽) none:隐藏元素 |
1 | div{ |
1 | <div> |

元素显示
1 | /* 把列表项显示为内联元素,无长宽*/ |
元素隐藏
当设置为none时,可以隐藏元素。
1 | /*背景图片*/ |
1 |
|
HTTP:Hyper Text Transfer Protocol,意为超文本传输协议,是建立在 TCP/IP 协议基础上,指的是服务器和客户端之间交互必须遵循的一问一答的规则,形容这个规则:问答机制、握手机制
HTTP 协议是一个无状态的面向连接的协议,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。所以打开一个服务器上的网页和上一次打开这个服务器上的网页之间没有任何联系
注意:无状态并不是代表 HTTP 就是 UDP,面向连接也不是代表 HTTP 就是TCP
HTTP 作用:用于定义 WEB 浏览器与 WEB 服务器之间交换数据的过程和数据本身的内容
浏览器和服务器交互过程:浏览器请求,服务请求响应
URL 和 URI
URL:统一资源定位符
URI:统一资源标志符
区别:URL - HOST = URI,URI 是抽象的定义,URL 用地址定位,URI 用名称定位。只要能唯一标识资源的是 URI,在 URI 的基础上给出其资源的访问方式的是 URL
从浏览器地址栏输入 URL 到请求返回发生了什么?
进行 URL 解析,进行编码
DNS 解析,顺序是先查 hosts 文件是否有记录,有的话就会把相对应映射的 IP 返回,然后去本地 DNS 缓存中寻找,然后依次向本地域名服务器、根域名服务器、顶级域名服务器、权限域名服务器发起查询请求,最终返回 IP 地址给本地域名服务器
本地域名服务器将得到的 IP 地址返回给操作系统,同时将 IP 地址缓存起来;操作系统将 IP 地址返回给浏览器,同时自己也将 IP 地址缓存起来
查找到 IP 之后,进行 TCP 协议的三次握手建立连接
发出 HTTP 请求,取文件指令
服务器处理请求,返回响应
释放 TCP 连接
浏览器解析渲染页面
推荐阅读:https://xiaolincoding.com/network/
版本介绍:
HTTP 1.0 和 HTTP 1.1 的主要区别:
长短连接:
在HTTP/1.0中,默认使用的是短连接,每次请求都要重新建立一次连接,比如获取 HTML 和 CSS 文件,需要两次请求。HTTP 基于 TCP/IP 协议的,每一次建立或者断开连接都需要三次握手四次挥手,开销会比较大
HTTP 1.1起,默认使用长连接 ,默认开启 Connection: keep-alive,Keep-Alive 有一个保持时间,不会永久保持连接。持续连接有非流水线方式和流水线方式 ,流水线方式是客户端在收到 HTTP 的响应报文之前就能接着发送新的请求报文,非流水线方式是客户端在收到前一个响应后才能发送下一个请求
HTTP 协议的长连接和短连接,实质上是 TCP 协议的长连接和短连接
错误状态响应码:在 HTTP1.1 中新增了 24 个错误状态响应码,如 409(Conflict)表示请求的资源与资源的当前状态发生冲突,410(Gone)表示服务器上的某个资源被永久性的删除
缓存处理:在 HTTP1.0 中主要使用 header 里的 If-Modified-Since,Expires 来做为缓存判断的标准,HTTP1.1 则引入了更多的缓存控制策略,例如 Entity tag,If-Unmodified-Since,If-Match,If-None-Match等
带宽优化及网络连接的使用:HTTP1.0 存在一些浪费带宽的现象,例如客户端只需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1 则在请求头引入了 range 头域,允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接
HOST 头处理:在 HTTP1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此请求消息中的 URL 并没有传递主机名。HTTP1.1 时代虚拟主机技术发展迅速,在一台物理服务器上可以存在多个虚拟主机,并且共享一个 IP 地址,故 HTTP1.1 增加了 HOST 信息
HTTP 1.1 和 HTTP 2.0 的主要区别:
HTTP 和 HTTPS 的区别:
对称加密和非对称加密
对称加密:加密和解密使用同一个秘钥,把密钥转发给需要发送数据的客户机,中途会被拦截(类似于把带锁的箱子和钥匙给别人,对方打开箱子放入数据,上锁后发送),私钥用来解密数据,典型的对称加密算法有 DES、AES 等
非对称加密:加密和解密使用不同的秘钥,一把作为公开的公钥,另一把作为私钥,公钥公开给任何人(类似于把锁和箱子给别人,对方打开箱子放入数据,上锁后发送),典型的非对称加密算法有 RSA、DSA 等
使用对称加密和非对称加密的方式传送数据
思想:锁上加锁
名词解释:
哈希算法:通过哈希函数计算出内容的哈希值,传输到对端后会重新计算内容的哈希,进行哈希比对来校验内容的完整性
数字签名:附加在报文上的特殊加密校验码,可以防止报文被篡改。一般是通过私钥对内容的哈希值进行加密,公钥正常解密并对比哈希值后,可以确保该内容就是对端发出的,防止出现中间人替换的问题
数字证书:由权威机构给某网站颁发的一种认可凭证
HTTPS 工作流程:服务器端的公钥和私钥,用来进行非对称加密,客户端生成的随机密钥,用来进行对称加密

参考文章:https://www.cnblogs.com/linianhui/p/security-https-workflow.html
参考文章:https://www.jianshu.com/p/14cd2c9d2cd2
请求行: 永远位于请求的第一行
请求头: 从第二行开始,到第一个空行结束
请求体: 从第一个空行后开始,到正文的结束(GET 没有)
请求方式

GET
1 | 【请求行】 |
GET 和 POST 比较
作用:GET 用于获取资源,而 POST 用于传输实体主体
参数:GET 和 POST 的请求都能使用额外的参数,但是 GET 的参数是以查询字符串出现在 URL 中,而 POST 的参数存储在实体主体中(GET 也有请求体,POST 也可以通过 URL 传输参数)。不能因为 POST 参数存储在实体主体中就认为它的安全性更高,因为照样可以通过一些抓包工具(Fiddler)查看
安全:安全的 HTTP 方法不会改变服务器状态,也就是说它只是可读的。GET 方法是安全的,而 POST 不是,因为 POST 的目的是传送实体主体内容
幂等性:同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的,所有的安全方法也都是幂等的。在正确实现条件下,GET,HEAD,PUT 和 DELETE 等方法都是幂等的,POST 方法不是
可缓存:如果要对响应进行缓存,需要满足以下条件
PUT 和 POST 的区别
PUT 请求:如果两个请求相同,后一个请求会把第一个请求覆盖掉(幂等),所以 PUT 用来修改资源
POST 请求:后一个请求不会把第一个请求覆盖掉(非幂等),所以 POST 用来创建资源
PATCH 方法 是新引入的,是对 PUT 方法的补充,用来对已知资源进行局部更新
请求行详解
1 | GET /myApp/success.html?username=zs&password=123456 HTTP/1.1 |
| 内容 | 说明 |
|---|---|
| GET/POST | 请求的方式。 |
| /myApp/success.html | 请求的资源。 |
| HTTP/1.1 | 使用的协议,及协议的版本。 |
| 内容 | 说明 |
|---|---|
| Accept | 告知服务器,客户浏览器支持的 MIME 类型 |
| User-Agent | 浏览器相关信息 |
| Accept-Charset | 告诉服务器,客户浏览器支持哪种字符集 |
| Accept-Encoding | 告知服务器,客户浏览器支持的压缩编码格式,常用 gzip 压缩 |
| Accept-Language | 告知服务器,客户浏览器支持的语言,zh_CN 或 en_US 等 |
| Host | 初始 URL 中的主机和端口 |
| Referer | 告知服务器,当前请求的来源。只有当前请求有来源,才有这个消息头。 作用:1 投放广告 2 防盗链 |
| Content-Type | 告知服务器,请求正文的 MIME 类型,文件传输的类型, application/x-www-form-urlencoded |
| Content-Length | 告知服务器,请求正文的长度。 |
| Connection | 表示是否需要持久连接,一般是 Keep -Alive(HTTP 1.1 默认进行持久连接 ) |
| If-Modified-Since | 告知服务器,客户浏览器缓存文件的最后修改时间 |
| Cookie | 会话管理相关(非常的重要) |
请求体详解
只有 POST 请求方式,才有请求的正文,GET 方式的正文是在地址栏中的
表单的输入域有 name 属性的才会被提交,不分 GET 和 POST 的请求方式
表单的 enctype 属性取值决定了请求正文的体现形式
| enctype取值 | 请求正文体现形式 | 示例 |
|---|---|---|
| application/x-www-form-urlencoded | key=value&key=value | username=test&password=1234 |
| multipart/form-data | 此时变成了多部分表单数据。多部分是靠分隔符分隔的。 | —————————–7df23a16c0210 Content-Disposition: form-data; name=”username” test —————————–7df23a16c0210 Content-Disposition: form-data; name=”password” 1234 ——————————-7df23a16c0210 |
响应部分图:

响应行
HTTP/1.1:使用协议的版本
200:响应状态码
OK:状态码描述
响应状态码:
| 状态码 | 说明 |
|---|---|
| 200 | 一切都 OK,与服务器连接成功,发送请求成功 |
| 302/307 | 请求重定向(客户端行为,两次请求,地址栏发生改变) |
| 304 | 请求资源未改变,使用缓存 |
| 400 | 客户端错误,请求错误,最常见的就是请求参数有问题 |
| 403 | 客户端错误,但 forbidden 权限不够,拒绝处理 |
| 404 | 客户端错误,请求资源未找到 |
| 500 | 服务器错误,服务器运行内部错误 |
转移:
响应头:以 key:vaue 存在,可能多个 value 情况
| 消息头 | 说明 |
|---|---|
| Location | 请求重定向的地址,常与 302,307 配合使用。 |
| Server | 服务器相关信息 |
| Content-Type | 告知客户浏览器,响应正文的MIME类型 |
| Content-Length | 告知客户浏览器,响应正文的长度 |
| Content-Encoding | 告知客户浏览器,响应正文使用的压缩编码格式,常用的 gzip 压缩 |
| Content-Language | 告知客户浏览器,响应正文的语言,zh_CN 或 en_US 等 |
| Content-Disposition | 告知客户浏览器,以下载的方式打开响应正文 |
| Refresh | 客户端的刷新频率,单位是秒 |
| Last-Modified | 服务器资源的最后修改时间 |
| Set-Cookie | 服务器端发送的 Cookie,会话管理相关 |
| Expires:-1 | 服务器资源到客户浏览器后的缓存时间 |
| Catch-Control: no-catch | 不要缓存,//针对http协议1.1版本 |
| Pragma:no-catch | 不要缓存,//针对http协议1.0版本 |
响应体:页面展示内容, 类似网页的源码
1 | <html> |
JavaEE 规范是 J2EE 规范的新名称,早期被称为 J2EE 规范,其全称是 Java 2 Platform Enterprise Edition,它是由 SUN 公司领导、各厂家共同制定并得到广泛认可的工业标准(JCP组织成员)。之所以改名为JavaEE,目的还是让大家清楚 J2EE 只是 Java 企业应用。在 2004 年底中国软件技术大会 Ioc 微容器(也就是 Jdon 框架的实现原理)演讲中指出:我们需要一个跨 J2SE/WEB/EJB 的微容器,保护我们的业务核心组件,以延续它的生命力,而不是依赖 J2SE/J2EE 版本。此次 J2EE 改名为 Java EE,实际也反映出业界这种共同心声
JavaEE 规范是很多 Java 开发技术的总称。这些技术规范都是沿用自 J2EE 的。一共包括了 13 个技术规范,例如:jsp/servlet,jndi,jaxp,jdbc,jni,jaxb,jmf,jta,jpa,EJB等。
其中,JCP 组织的全称是 Java Community Process,是一个开放的国际组织,主要由 Java 开发者以及被授权者组成,职能是发展和更新。成立于 1998 年。官网是:JCP
JavaEE 的版本是延续了 J2EE 的版本,但是没有继续采用其命名规则。J2EE 的版本从 1.0 开始到 1.4 结束,而 JavaEE 版本是从 JavaEE 5 版本开始,目前最新的的版本是 JavaEE 8
详情请参考:JavaEE8 规范概览
Web,在计算机领域指网络。像我们接触的 WWW,它是由 3 个单词组成的,即:World Wide Web ,中文含义是万维网。而我们前面学的 HTML 的参考文档《W3School 全套教程》中的 W3C 就是万维网联盟,他们的出现都是为了让我们在网络的世界中获取资源,这些资源的存放之处,我们称之为网站。我们通过输入网站的地址(网址),就可以访问网站中提供的资源。在网上我们能访问到的内容全是资源(不区分局域网还是广域网),只不过不同类型的资源展示的效果不一样
资源分为静态资源和动态资源
静态资源指的是,网站中提供给人们展示的资源是一成不变的,也就是说不同人或者在不同时间,看到的内容都是一样的。例如:我们看到的新闻,网站的使用手册,网站功能说明文档等等。而作为开发者,我们编写的 html、css、js 图片,多媒体等等都可以称为静态资源
动态资源它指的是,网站中提供给人们展示的资源是由程序产生的,在不同的时间或者用不同的人员由于身份的不同,所看到的内容是不一样的。例如:我们在CSDN上下载资料,只有登录成功后,且积分足够时才能下载。否则就不能下载,这就是访客身份和会员身份的区别。作为开发人员,我们编写的 JSP,servlet,php,ASP 等都是动态资源。
关于广域网和局域网的划分
基础结构划分:C/S结构,B/S结构两类。
技术选型划分:Model1模型,Model2模型,MVC模型和三层架构+MVC模型。
部署方式划分:一体化架构,垂直拆分架构,分布式架构,流动计算架构,微服务架构。
C/S结构:客户端—服务器的方式。其中C代表Client,S代表服务器。C/S结构的系统设计图如下:

B/S结构是浏览器—服务器的方式。B代表Browser,S代表服务器。B/S结构的系统设计图如下:

两种结构的区别及优劣
区别:
优劣
我们的课程中涉及的系统结构都是是基于B/S结构
服务器的概念非常的广泛,它可以指代一台特殊的计算机(相比普通计算机运行更快、负载更高、价格更贵),也可以指代用于部署网站的应用。我们这里说的服务器,其实是web服务器,或者应用服务器。它本质就是一个软件,一个应用。作用就是发布我们的应用(工程),让用户可以通过浏览器访问我们的应用。
常见的应用服务器,请看下表:
| 服务器名称 | 说明 |
|---|---|
| weblogic | 实现了 JavaEE 规范,重量级服务器,又称为 JavaEE 容器 |
| websphereAS | 实现了 JavaEE 规范,重量级服务器。 |
| JBOSSAS | 实现了 JavaEE 规范,重量级服务器,免费 |
| Tomcat | 实现了 jsp/servlet 规范,是一个轻量级服务器,开源免费 |
下载地址:http://tomcat.apache.org/
目录结构详解:

解压apache-tomcat-8.5.32.tar.gz。
防火墙设置
方式1:service iptables stop 关闭防火墙(不建议); 用到哪一个端口号就放行哪一个(80,8080,3306…)
方式2:放行8080 端口
cd /etc/sysconfig–>vi iptables-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPTservice iptables reload 或者service iptables restartTomcat服务器的启动文件在二进制文件目录bin中:startup.bat,startup.sh
Tomcat服务器的停止文件也在二进制文件目录bin中:shutdown.bat,shutdown.sh (推荐直接关闭控制台)
其中.bat文件是针对windows系统的运行程序,.sh文件是针对linux系统的运行程序。
启动一闪而过
没有配置环境变量,配置上 JAVA_HOME 环境变量。
Tomcat 启动后控制台输出乱码
打开 /conf/logging.properties,设置 gbk java.util.logging.ConsoleHandler.encoding = gbk
Address already in use : JVM_Bind:端口被占用,找到占用该端口的应用
进程不重要:使用cmd命令:netstat -a -o 查看 pid 在任务管理器中结束占用端口的进程
进程很重要:修改自己的端口号。修改的是 Tomcat 目录下\conf\server.xml中的配置。

Run -> Edit Configurations -> Templates -> Tomcat Server -> Local

在 server.xml 的 <Host> 元素中加一个 <Context path="" docBase=""/> 元素
path:访问资源URI,URI名称可以随便起,但是必须在前面加上一个/docBase:资源所在的磁盘物理地址在<Engine>元素中添加一个<Host name="" appBase="" unparkWARs="" autoDeploy="" />,其中:
name:指定主机的名称appBase:当前主机的应用发布目录unparkWARs:启动时是否自动解压war包autoDeploy:是否自动发布1 | <Host name="www.itcast.cn" appBase="D:\itcastapps" unpackWARs="true" autoDeploy="true"/> |
新建工程

发布工程
Run
把资源移动到 Tomcat 工程下 web 目录中,两种访问方式
在 web.xml 中配置默认主页
1 | <welcome-file-list> |
Tomcat 核心组件架构图如下所示:

组件介绍:
核心类库:
参考文章:https://www.jianshu.com/p/7c9401b85704
参考文章:https://www.yuque.com/yinhuidong/yu877c/ktq82e
Tomcat 的启动入口是 Bootstrap#main 函数,首先通过调用 bootstrap.init() 初始化相关组件:
initClassLoaders():初始化三个类加载器,commonLoader 的父类加载器是启动类加载器Thread.currentThread().setContextClassLoader(catalinaLoader):自定义类加载器加载 Catalina 类,打破双亲委派Object startupInstance = startupClass.getConstructor().newInstance():反射创建 Catalina 对象method.invoke(startupInstance, paramValues):反射调用方法,设置父类加载器是 sharedLoadercatalinaDaemon = startupInstance:引用 Catalina 对象daemon.load(args) 方法反射调用 Catalina 对象的 load 方法,对服务器的组件进行初始化,并绑定了 ServerSocket 的端口:
parseServerXml(true):解析 XML 配置文件
getServer().init():服务器执行初始化,采用责任链的执行方式
LifecycleBase.init():生命周期接口的初始化方法,开始链式调用
StandardServer.initInternal():Server 的初始化,遍历所有的 Service 进行初始化
StandardService.initInternal():Service 的初始化,对 Engine、Executor、listener、Connector 进行初始化
StandardEngine.initInternal():Engine 的初始化
getRealm():创建一个 Realm 对象ContainerBase.initInternal():容器的初始化,设置处理容器内组件的启动和停止事件的线程池Connector.initInternal():Connector 的初始化
1 | public Connector() { |
adapter = new CoyoteAdapter(this):实例化 CoyoteAdapter 对象
protocolHandler.setAdapter(adapter):设置到 ProtocolHandler 协议处理器中
ProtocolHandler.init():协议处理器的初始化,底层调用 AbstractProtocol#init 方法
endpoint.init():端口的初始化,底层调用 AbstractEndpoint#init 方法
NioEndpoint.bind():绑定方法
initServerSocket():初始化 ServerSocket,以 NIO 的方式监听端口serverSock = ServerSocketChannel.open():NIO 的方式打开通道serverSock.bind(addr, getAcceptCount()):通道绑定连接端口serverSock.configureBlocking(true):切换为阻塞模式(没懂,为什么阻塞)initialiseSsl():初始化 SSL 连接selectorPool.open(getName()):打开选择器,类似 NIO 的多路复用器初始化完所有的组件,调用 daemon.start() 进行组件的启动,底层反射调用 Catalina 对象的 start 方法:
getServer().start():启动组件,也是责任链的模式
LifecycleBase.start():生命周期接口的初始化方法,开始链式调用
StandardServer.startInternal():Server 服务的启动
globalNamingResources.start():启动 JNDI 服务for (Service service : services):遍历所有的 Service 进行启动StandardService.startInternal():Service 的启动,对所有 Executor、listener、Connector 进行启
StandardEngine.startInternal():启动引擎,部署项目
ContainerBase.startInternal():容器的启动((Lifecycle) pipeline).start():遍历所有的管道进行启动Valve current = first:获取第一个阀门((Lifecycle) current).start():启动阀门,底层 ValveBase#startInternal 中设置启动的状态current = current.getNext():获取下一个阀门Connector.startInternal():Connector 的初始化
protocolHandler.start():协议处理器的启动
endpoint.start():端点启动
NioEndpoint.startInternal():启动 NIO 的端点
createExecutor():创建 Worker 线程组,10 个线程,用来进行任务处理initializeConnectionLatch():用来进行连接限流,最大 8*1024 条连接poller = new Poller():创建 Poller 对象,开启了一个多路复用器 SelectorThread pollerThread = new Thread(poller, getName() + "-ClientPoller"):创建并启动 Poller 线程,Poller 实现了 Runnable 接口,是一个任务对象,线程 start 后进入 Poller#run 方法pollerThread.setDaemon(true):设置为守护线程startAcceptorThread():启动接收者线程acceptor = new Acceptor<>(this):创建 Acceptor 对象Thread t = new Thread(acceptor, threadName):创建并启动 Acceptor 接受者线程serverSocket.accept**,获取 Socket 后把封装成 NioSocketWrapper(是 SocketWrapperBase 的子类),并设置为非阻塞模式,把 NioSocketWrapper 封装成 PollerEvent 放入同步队列中selector.selectedKeys() 获取就绪事件,获取 SocketChannel 中携带的 attachment(NioSocketWrapper),在 processKey 方法中根据事件类型进行 processSocket,将 Wrapper 对象封装成 SocketProcessor 对象,该对象是一个任务对象,提交到 Worker 线程池进行执行SocketProcessorBase.run() 加锁调用 SocketProcessor#doRun,保证线程安全,从协议处理器 ProtocolHandler 中获取 AbstractProtocol,然后创建 Http11Processor 对象处理请求Http11Processor#service 中调用 CoyoteAdapter#service ,把生成的 Tomcat 下的 Request 和 Response 对象通过方法 postParseRequest 匹配到对应的 Servlet 的请求响应,将请求传递到对应的 Engine 容器中调用 Pipeline,管道中包含若干个 Valve,执行完所有的 Valve 最后执行 StandardEngineValve,继续调用 Host 容器的 Pipeline,执行 Host 的 Valve,再传递给 Context 的 Pipeline,最后传递到 Wrapper 容器StandardWrapperValve#invoke 中创建了 Servlet 对象并执行初始化,并为当前请求准备一个 FilterChain 过滤器链执行 doFilter 方法,ApplicationFilterChain#doFilter 是一个责任链的驱动方法,通过调用 internalDoFilter 来获取过滤器链的下一个过滤器执行 doFilter,执行完所有的过滤器后执行 servlet.service 的方法Socket 是使用 TCP/IP 或者 UDP 协议在服务器与客户端之间进行传输的技术,是网络编程的基础
Tomcat 和 Servlet 的关系:Servlet 的运行环境叫做 Web 容器或 Servlet 服务器,Tomcat 是 Web 应用服务器,是一个 Servlet/JSP 容器。Tomcat 作为 Servlet 容器,负责处理客户请求,把请求传送给 Servlet,并将 Servlet 的响应传送回给客户。而 Servlet 是一种运行在支持 Java 语言的服务器上的组件,Servlet 用来扩展 Java Web 服务器功能,提供非常安全的、可移植的、易于使用的 CGI 替代品
Servlet是SUN公司提供的一套规范,名称就叫Servlet规范,它也是JavaEE规范之一。通过API来使用Servlet。
Servlet是一个运行在web服务端的java小程序,用于接收和响应客户端的请求。一个服务器包含多个Servlet
通过实现Servlet接口,继承GenericServlet或者HttpServlet,实现Servlet功能
每次请求都会执行service方法,在service方法中还有参数ServletRequest和ServletResponse
支持配置相关功能

创建 Web 工程 → 编写普通类继承 Servlet 相关类 → 重写方法

Servlet执行过程分析:
通过浏览器发送请求,请求首先到达Tomcat服务器,由服务器解析请求URL,然后在部署的应用列表中找到应用。然后找到web.xml配置文件,在web.xml中找到FirstServlet的配置(

实现 Servlet 功能时,可以选择以下三种方式:
第一种:实现 Servlet 接口,接口中的方法必须全部实现。
使用此种方式,表示接口中的所有方法在需求方面都有重写的必要。此种方式支持最大程度的自定义。
第二种:继承 GenericServlet,service 方法必须重写,其他方可根据需求,选择性重写。
使用此种方式,表示只在接收和响应客户端请求这方面有重写的需求,而其他方法可根据实际需求选择性重写,使我们的开发Servlet变得简单。但是,此种方式是和 HTTP 协议无关的。
第三种:继承 HttpServlet,它是 javax.servlet.http 包下的一个抽象类,是 GenericServlet 的子类。选择继承 HttpServlet 时,需要重写 doGet 和 doPost 方法,来接收 get 方式和 post 方式的请求,不要覆盖 service 方法。使用此种方式,表示我们的请求和响应需要和 HTTP 协议相关,我们是通过 HTTP 协议来访问。每次请求和响应都符合 HTTP 协议的规范。请求的方式就是 HTTP 协议所支持的方式(GET POST PUT DELETE TRACE OPTIONS HEAD )。
Servlet 3.0 中的异步处理指的是允许Servlet重新发起一条新线程去调用 耗时业务方法,这样就可以避免等待

servlet从创建到销毁的过程:
出生:(初始化)请求第一次到达 Servlet 时,创建对象,并且初始化成功。Only one time
活着:(服务)服务器提供服务的整个过程中,该对象一直存在,每次只是执行 service 方法
死亡:(销毁)当服务停止时,或者服务器宕机时,对象删除,
serrvlet生命周期方法:init(ServletConfig config) → service(ServletRequest req, ServletResponse res) → destroy()
默认情况下, 有了第一次请求, 会调用 init() 方法进行初始化【调用一次】,任何一次请求,都会调用 service() 方法处理这个请求,服务器正常关闭或者项目从服务器移除, 调用 destory() 方法进行销毁【调用一次】
扩展:servlet 是单例多线程的,尽量不要在 servlet 里面使用全局(成员)变量,可能会导致线程不安全
Servlet运用了单例模式,整个应用中只有一个实例对象,所以需要分析这个唯一的实例中的类成员是否线程安全
1 | public class ServletDemo extends HttpServlet{ |
启动两个浏览器,输入不同的参数(http://localhost:8080/ServletDemo/username=aaa 或者bbb),访问之后发现输出的结果都是一样,所以出现线程安全问题。
在Servlet中定义了类成员之后,多个浏览器都会共享类成员的数据,其中任何一个线程修改了数据,都会影响其他线程。因此,我们可以认为Servlet它不是线程安全的。因为Servlet是单例,单例对象的类成员只会随类实例化时初始化一次,之后的操作都是改变,而不会重新初始化。
解决办法:如果类成员是共用的,只在初始化时赋值,其余时间都是获取。或者加锁synchronized
Servlet支持三种映射方式,三种映射方式的优先级为:第一种>第二种>第三种。
具体名称方式
这种方式,只有和映射配置一模一样时,Servlet才会接收和响应来自客户端的请求。
访问URL:http://localhost:8080/servlet/servletDemo
1 | <servlet> |
/开头+通配符的方式
这种方式,只要符合目录结构即可,不用考虑结尾是什么
访问URL:http://localhost:8080/servlet/ + 任何字符
1 | <servlet> |
通配符+固定格式结尾
这种方式,只要符合固定结尾格式即可,其前面的访问URI无须关心(注意协议,主机和端口必须正确)
访问URL:http://localhost:8080/任何字符任何目录 + .do (http://localhost:8080/seazean/i.do)
1 | <servlet> |
一个Servlet的多种路径配置的支持。给一个Servlet配置多个访问映射,从而根据不同请求的URL实现不同的功能
1 | /*多路映射*/ |
1 | <!--演示Servlet多路径映射--> |
这样就可以根据不同的网页显示不同的数据。
在web.xml中是支持对Servlet的创建时机进行配置的,配置的方式如下:
1 | <!--配置ServletDemo3--> |
默认 Servlet 是由服务器提供的一个 Servlet,它配置在 Tomcat 的 conf 目录下的 web.xml 中。
它的映射路径是<url-pattern>/<url-pattern>,我们在发送请求时,首先会在我们应用中的 web.xml 中查找映射配置。但是当找不到对应的 Servlet 路径时,就去找默认的 Servlet,由默认 Servlet 处理。
ServletConfig 是 Servlet 的配置参数对象。在 Servlet 规范中,允许为每个 Servlet 都提供一些初始化配置,每个 Servlet 都有自己的ServletConfig,作用是在 Servlet 初始化期间,把一些配置信息传递给 Servlet
生命周期:在初始化阶段读取了 web.xml 中为 Servlet 准备的初始化配置,并把配置信息传递给 Servlet,所以生命周期与 Servlet 相同。如果 Servlet 配置了 <load-on-startup>1</load-on-startup>,ServletConfig 也会在应用加载时创建。
获取 ServletConfig:在 init 方法中为 ServletConfig 赋值
常用API:
String getInitParameter(String name):根据初始化参数的名称获取参数的值,根据Enumeration<String> getInitParameterNames() : 获取所有初始化参数名称的枚举(遍历方式看例子)ServletContext getServletContext() : 获取ServletContext对象String getServletName() : 获取Servlet名称代码实现:
web.xml 配置:
初始化参数使用 <servlet> 标签中的 <init-param> 标签来配置,并且每个 Servlet 都支持有多个初始化参数,并且初始化参数都是以键值对的形式存在的
1 | <!--配置ServletDemo8--> |
代码:
1 | //演示Servlet的初始化参数对象 |
效果:

ServletContext 对象是应用上下文对象。服务器为每一个应用都创建了一个 ServletContext 对象,ServletContext 属于整个应用,不局限于某个 Servlet,可以实现让应用中所有 Servlet 间的数据共享。
上下文代表了程序当下所运行的环境,联系整个应用的生命周期与资源调用,是程序可以访问到的所有资源的总和,资源可以是一个变量,也可以是一个对象的引用
生命周期:
域对象:指的是对象有作用域,即有作用范围,可以实现数据共享,不同作用范围的域对象,共享数据的能力不一样。
Servlet 规范中,共有4个域对象,ServletContext 是其中一个,web 应用中最大的作用域,叫 application 域,可以实现整个应用间的数据共享功能。
数据共享:
获取ServletContext:
Java 项目继承 HttpServlet,HttpServlet 继承 GenericServlet,GenericServlet 中有一个方法可以直接使用
1 | public ServletContext getServletContext() { |
ServletRequest 类方法:
1 | ServletContext getServletContext()//获取ServletContext对象 |
常用API:
String getInitParameter(String name) : 根据名称获取全局配置的参数String getContextPath : 获取当前应用访问的虚拟目录String getRealPath(String path) : 根据虚拟目录获取应用部署的磁盘绝对路径void setAttribute(String name, Object object) : 向应用域对象中存储数据Object getAttribute(String name) : 根据名称获取域对象中的数据,没有则返回nullvoid removeAttribute(String name) : 根据名称移除应用域对象中的数据代码实现:
web.xml配置:
配置的方式,需要在<web-app>标签中使用<context-param>来配置初始化参数,它的配置是针对整个应用的配置,被称为应用的初始化参数配置。
1 | <!--配置应用初始化参数--> |
代码:
1 | public class ServletContextDemo extends HttpServlet { |
Servlet3.0 版本!不需要配置 web.xml
注解案例
1 |
|
WebServlet注解(@since Servlet 3.0 (Section 8.1.1))
1 |
|
手动创建容器:(了解)
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。

请求:客户机希望从服务器端索取一些资源,向服务器发出询问
请求对象:在 JavaEE 工程中,用于发送请求的对象,常用的对象是 ServletRequest 和 HttpServletRequest ,它们的区是是否与 HTTP 协议有关
Request 作用:

| 方法 | 作用 |
|---|---|
| String getLocalAddr() | 获取本机(服务器)地址 |
| String getLocalName() | 获取本机(服务器)名称 |
| int getLocalPort() | 获取本机(服务器)端口 |
| String getRemoteAddr() | 获取访问者IP |
| String getRemoteHost | 获取访问者主机 |
| int getRemotePort() | 获取访问者端口 |
| String getMethod(); | 获得请求方式 |
| String getRequestURI() | 获取统一资源标识符(/request/servletDemo01) |
| String getRequestURL() | 获取统一资源定位符(http://localhost:8080/request/servletDemo01) |
| String getQueryString() | 获取请求消息的数据 (GET方式 URL中带参字符串:username=aaa&password=123) |
| String getContextPath() | 获取虚拟目录名称(/request) |
| String getServletPath | 获取Servlet映射路径 ( |
| String getRealPath(String path) | 根据虚拟目录获取应用部署的磁盘绝对路径 |
URL = URI + HOST
URL = HOST + ContextPath + ServletPath
| 方法 | 作用 |
|---|---|
| String getHeader(String name) | 获得指定请求头的值。 如果没有该请求头返回null,有多个值返回第一个 |
| Enumeration |
获取指定请求头的多个值 |
| Enumeration |
获取所有请求头名称的枚举 |
1 |
|
请求参数是正文部分标签内容,